进程/线程操作

1.为什么要进行线程/进程间的同步?
因为存在多个线程或者进程需要访问相同的资源。如果不进行同步,可能导致错误发生。比如因读写的不同步造成的数据错误,或者死锁的出现等,让系统和数据进入到一种错误或者不稳定的状态。

2.使用了多线程就必须要进行同步么?
大部分情况下是这样,但也不能绝对。 因为需要进行同步的情况需要满足两个条件:

a.存在多个线程/进程

b.多个线程/进程之间会相互的竞争资源

如果只是存在多个线程/进程,但只见并没有竟让共有资源,那也没必要进行同步。 如线程内的局部变量等数据

3.进行同步的机制都有什么?
比如加互斥锁,临界区,信号量等。

互斥锁: 一次只允许一个线程进入共享区域,在离开共享区域时释放锁。

临界区: 类似互斥锁

信号量: 维护一个数,允许特定数量的线程进入

4.什么是原子操作。

原子操作就是一组不可分离的操作。应该把它视为一个整体,要么全部成功,要么全部失败,不会出现部分成功,部分失败的现象。而且原子操作执行中间不会被打断。

5.原子操作的不会被打断是什么意思,是说线程不会被切换么?
不是的。

有的原子操作是由处理器本身所支持的。 如一条指令本身肯定是一个原子操作。

但有的原子操作是一个执行块,这时在这个执行块中间,是非常有可能发生线程间的切换的。

有时候,一条高级语言的语句可能会被编译成好几条对应的汇编语句(机器语句) 如 c = a+b; 很有可能还没有算出c的结果线程就被切换了。
但发生线程间的切换并不意味着数据就可以被其他的线程访问。因为我们可以通过加锁的办法,让其他线程不能进入到执行块内部。这样其他线程虽然获得了CPU时间,但如果要访问执行块,只有等待,别的什么也做不了。数据还是安全的。

6.锁和原子操作是一个概念么。
原子操作是一个不可被分割的单个或者多个操作。
锁是一种机制,让我们来协调各个线程,来实现原子操作。
原子操作 分为物理的 和 软件实现的两种
物理的比如一条单独的汇编语句。
软件实现的往往依赖于锁

7. 什么是死锁。
如在一个单轨的铁路上,两条火车向不同的方向开。 谁也动不了了

8.为什么会发生死锁
死锁一般都是由于对共享资源的竞争引起的。 但对共享资源的竞争又不一定就会发生死锁。 死锁的发生必须同时满足四个条件:互斥,持有/等待,非抢占, 形成等待环

9.什么是活锁
活锁和死锁很像似。 只是活锁的状态可以发生改变。不过虽然状态可以改变,却没有实质的进展。
活锁一般是由于对死锁的不正确处理引起的。由于处于死锁中的多个线程同时采取了行动。 而避免的方法也是只让一个线程释放资源。
比如两个人在一个很宅的胡同里。 一次只能并排过两个人。 两人比较礼貌,都要给对方让路。 结果一起要么让到左边,要么让到右边,结果仍然是谁也过不去。 类似于原地踏步或者震荡状态。

10. 什么是饿死
饿死(starvation) 是一个线程长时间得不到需要的资源而不能执行的现象。 有人饿死并不代表着出现了死锁。很有可能系统还能很好的进行。
所以,没有出现死锁并不能就认为系统是完好的。还要保证没有出现饿死的现象。
避免饿死就应该是采用队列的方式,保证每个人都有机会获得请求的资源。 当然实现方式可以很多个变化,比如优先级,时间片,等,都是“队列”的特殊形式

Jerky Lu wechat
欢迎加入微信公众号